﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using gts;
using System.Runtime.InteropServices;

namespace GCard
{
    public partial class HomePage : Form
    {
        public HomePage()
        {
            InitializeComponent();
            //InitalPanel();
        }

        private void HomePage_Load(object sender, EventArgs e)
        {
            InitalPanel();
        }

        GtsCard gCard = new GtsCard();
        //初始化界面
        private void InitalPanel()
        {
            this.cmb_selectAxis.DropDownStyle = ComboBoxStyle.DropDownList;  //轴号初始化
            this.cmb_selectAxis.Text = this.cmb_selectAxis.Items[0].ToString();//设置默认值

            this.cmb_home.DropDownStyle = ComboBoxStyle.DropDownList;  //home方式初始化
            this.cmb_home.Text = this.cmb_home.Items[0].ToString();//设置默认值

            this.cmb_moveDir.DropDownStyle = ComboBoxStyle.DropDownList;  //回零方向初始化
            this.cmb_moveDir.Text = this.cmb_moveDir.Items[0].ToString();//设置默认值

            this.cmb_indexDir.DropDownStyle = ComboBoxStyle.DropDownList;  //index方向初始化
            this.cmb_indexDir.Text = this.cmb_indexDir.Items[0].ToString();//设置默认值

            this.cmb_gearAxis.DropDownStyle = ComboBoxStyle.DropDownList;  //gearAxis方式初始化
            this.cmb_gearAxis.Text = this.cmb_gearAxis.Items[1].ToString();//设置默认值

            this.cmb_gearMode.DropDownStyle = ComboBoxStyle.DropDownList;  //gearMode方式初始化
            this.cmb_gearMode.Text = this.cmb_gearMode.Items[0].ToString();//设置默认值

            this.cmb_followAxis.DropDownStyle = ComboBoxStyle.DropDownList;  //followAxis方式初始化
            this.cmb_followAxis.Text = this.cmb_followAxis.Items[1].ToString();//设置默认值

            this.cmb_followMode.DropDownStyle = ComboBoxStyle.DropDownList;  //followMode方式初始化
            this.cmb_followMode.Text = this.cmb_followMode.Items[0].ToString();//设置默认值

            this.cmb_cb.DropDownStyle = ComboBoxStyle.DropDownList;  //插补类型方式初始化
            this.cmb_cb.Text = this.cmb_cb.Items[0].ToString();//设置默认值

            this.cmb_compareMode.DropDownStyle = ComboBoxStyle.DropDownList;  //插补类型方式初始化
            this.cmb_compareMode.Text = this.cmb_compareMode.Items[0].ToString();//设置默认值
           
        }

        //HomePage界面
        short sRtn;     //返回值
        int servoValue;     //使能信号状态值
        PictureBox[] picS = new PictureBox[8]; //使能状态灯
        string pictrueServoStatus;
        Thread threadScan;//查询伺服状态
        Thread threadPos; //查询位置
        public void ServoStatus()
        {
            if (threadScan == null)
            {
                threadScan = new Thread(() =>
                {
                    for (int i = 0; i < 8; i++)
                    {
                        pictrueServoStatus = "picS" + (i).ToString();
                        picS[i] = (PictureBox)(this.Controls.Find(pictrueServoStatus, true)[0]);
                    }
                    while (true)
                    {
                        for (short i = 0; i < 8; i++)
                        {
                            sRtn = gts.mc.GT_GetDo(0, gts.mc.MC_ENABLE, out servoValue);
                            if (((1 << i) & servoValue) == 0)
                            {
                                Thread.Sleep(5);
                                picS[i].Invoke(new Action(() => { picS[i].BackgroundImage = Resource._red; }));
                            }
                            else
                            {
                                Thread.Sleep(5);
                                picS[i].Invoke(new Action(() => { picS[i].BackgroundImage = Resource._green; }));
                            }
                        }
                    }
                });
                threadScan.IsBackground = true;
                threadScan.Start();
            }
        }

        uint pClock;                //时钟信号
        double pEnc1, pEnc2, pEnc3, pEnc4, pEnc5, pEnc6, pEnc7, pEnc8;//编码器
        double pPrf1, pPrf2, pPrf3, pPrf4, pPrf5, pPrf6, pPrf7, pPrf8;//规划器
        public void PrfEncPos()
        {
            if (threadPos == null)
            {
                threadPos = new Thread(() =>
                {
                    while (true)
                    {
                        Thread.Sleep(10);
                        sRtn = gts.mc.GT_GetEncPos(0, 1, out pEnc1, 1, out pClock);//编码器位置
                        sRtn = gts.mc.GT_GetEncPos(0, 2, out pEnc2, 1, out pClock);
                        sRtn = gts.mc.GT_GetEncPos(0, 3, out pEnc3, 1, out pClock);
                        sRtn = gts.mc.GT_GetEncPos(0, 4, out pEnc4, 1, out pClock);
                        sRtn = gts.mc.GT_GetEncPos(0, 5, out pEnc5, 1, out pClock);
                        sRtn = gts.mc.GT_GetEncPos(0, 6, out pEnc6, 1, out pClock);
                        sRtn = gts.mc.GT_GetEncPos(0, 7, out pEnc7, 1, out pClock);
                        sRtn = gts.mc.GT_GetEncPos(0, 8, out pEnc8, 1, out pClock);

                        sRtn = gts.mc.GT_GetPrfPos(0, 1, out pPrf1, 1, out pClock);//规划器位置
                        sRtn = gts.mc.GT_GetPrfPos(0, 2, out pPrf2, 1, out pClock);
                        sRtn = gts.mc.GT_GetPrfPos(0, 3, out pPrf3, 1, out pClock);
                        sRtn = gts.mc.GT_GetPrfPos(0, 4, out pPrf4, 1, out pClock);
                        sRtn = gts.mc.GT_GetPrfPos(0, 5, out pPrf5, 1, out pClock);
                        sRtn = gts.mc.GT_GetPrfPos(0, 6, out pPrf6, 1, out pClock);
                        sRtn = gts.mc.GT_GetPrfPos(0, 7, out pPrf7, 1, out pClock);
                        sRtn = gts.mc.GT_GetPrfPos(0, 8, out pPrf8, 1, out pClock);
                        if (this.IsHandleCreated)
                        {
                            groupBox1.BeginInvoke(new Action(() =>
                            {
                                txt_prf1.Text = Convert.ToString(pPrf1);
                                txt_prf2.Text = Convert.ToString(pPrf2);
                                txt_prf3.Text = Convert.ToString(pPrf3);
                                txt_prf4.Text = Convert.ToString(pPrf4);
                                txt_prf5.Text = Convert.ToString(pPrf5);
                                txt_prf6.Text = Convert.ToString(pPrf6);
                                txt_prf7.Text = Convert.ToString(pPrf7);
                                txt_prf8.Text = Convert.ToString(pPrf8);

                                txt_enc1.Text = Convert.ToString(pEnc1);
                                txt_enc2.Text = Convert.ToString(pEnc2);
                                txt_enc3.Text = Convert.ToString(pEnc3);
                                txt_enc4.Text = Convert.ToString(pEnc4);
                                txt_enc5.Text = Convert.ToString(pEnc5);
                                txt_enc6.Text = Convert.ToString(pEnc6);
                                txt_enc7.Text = Convert.ToString(pEnc7);
                                txt_enc8.Text = Convert.ToString(pEnc8);

                            }));
                        }
                    }
                });
                threadPos.IsBackground = true;
                threadPos.Start();
            }
        }
        //使能控制，报警状态或其他指令返回值错误情况下，不能上使能
        private void btn_manuServoOn_Click(object sender, EventArgs e)//单轴使能
        {
            sRtn = gts.mc.GT_ClrSts(0, (short)(cmb_selectAxis.SelectedIndex + 1), 1);
            sRtn = gts.mc.GT_AxisOn(0, (short)(cmb_selectAxis.SelectedIndex + 1));
        }

        private void btn_manuServoOff_Click(object sender, EventArgs e)//单轴下使能
        {
            sRtn = gts.mc.GT_ClrSts(0, (short)(cmb_selectAxis.SelectedIndex + 1), 1);
            sRtn = gts.mc.GT_AxisOff(0, (short)(cmb_selectAxis.SelectedIndex + 1));
        }

        private void btn_manuServoOnAll_Click(object sender, EventArgs e)//多轴使能
        {
            gCard.MCAxisOnAll(0, 8);
        }

        private void btn_manuServoOffAll_Click(object sender, EventArgs e)//多轴下使能
        {
            gCard.MCAxisOffAll(0, 8);
        }

        //位置清零，正常只有在回原点完成后才能清零。
        private void btn_zeroPos1_Click(object sender, EventArgs e)
        {
            sRtn = mc.GT_ZeroPos(0, 1, 1);
        }

        private void btn_zeroPos2_Click(object sender, EventArgs e)
        {
            sRtn = mc.GT_ZeroPos(0, 2, 1);
        }

        private void btn_zeroPos3_Click(object sender, EventArgs e)
        {
            sRtn = mc.GT_ZeroPos(0, 3, 1);
        }

        private void btn_zeroPos4_Click(object sender, EventArgs e)
        {
            sRtn = mc.GT_ZeroPos(0, 4, 1);
        }

        private void btn_zeroPos5_Click(object sender, EventArgs e)
        {
            sRtn = mc.GT_ZeroPos(0, 5, 1);
        }

        private void btn_zeroPos6_Click(object sender, EventArgs e)
        {
            sRtn = mc.GT_ZeroPos(0, 6, 1);
        }

        private void btn_zeroPos7_Click(object sender, EventArgs e)
        {
            sRtn = mc.GT_ZeroPos(0, 7, 1);
        }

        private void btn_zeroPos8_Click(object sender, EventArgs e)
        {
            sRtn = mc.GT_ZeroPos(0, 8, 1);
        }

        private void JogPDown(object sender, MouseEventArgs e)
        {
            mc.TJogPrm tJogPrm = new mc.TJogPrm { acc = 1, dec = 1, smooth = 0.5 };
            gCard.JOG(0, (short)(cmb_selectAxis.SelectedIndex + 1), tJogPrm, (double)nud_vel1.Value);
        }

        private void JogPUp(object sender, MouseEventArgs e)
        {
            sRtn = gts.mc.GT_Stop(0, 1 << (short)(cmb_selectAxis.SelectedIndex + 1)-1, 0);
        }

        private void JogNDown(object sender, MouseEventArgs e)
        {
            mc.TJogPrm tJogPrm = new mc.TJogPrm { acc = 1, dec = 1, smooth = 0.5 };
            gCard.JOG(0, (short)(cmb_selectAxis.SelectedIndex + 1), tJogPrm, -(double)nud_vel1.Value);
        }

        private void JogNUp(object sender, MouseEventArgs e)
        {
            sRtn = gts.mc.GT_Stop(0, 1 << (short)(cmb_selectAxis.SelectedIndex + 1)-1, 0);
        }

        private void btn_moveInc_Click(object sender, EventArgs e)
        {
            gCard.P2PInc(0, (short)(cmb_selectAxis.SelectedIndex + 1), (double)nud_velMoveInc.Value, 1, 1, Convert.ToInt32(txt_posInc.Text));
        }

        private void btn_stopMoveInc_Click(object sender, EventArgs e)
        {
            sRtn = gts.mc.GT_Stop(0, 1 << (short)(cmb_selectAxis.SelectedIndex + 1)-1, 0);
        }

        private void btn_moveAbs_Click(object sender, EventArgs e)
        {
            gCard.P2PAbs(0, (short)(cmb_selectAxis.SelectedIndex + 1), (double)nud_velMoveAbs.Value, 1, 1, Convert.ToInt32(txt_posAbs.Text));
        }

        private void btn_stopMoveAbs_Click(object sender, EventArgs e)
        {
            sRtn = gts.mc.GT_Stop(0, 1 << (short)(cmb_selectAxis.SelectedIndex + 1)-1, 0);
        }

        Thread threadHome;
        Thread threadHomeStatus;
        private void btn_homeStart_Click(object sender, EventArgs e)
        {
            short axisHome;
            axisHome = (short)(cmb_selectAxis.SelectedIndex + 1);
            mc.THomeStatus tHomeStatus = new mc.THomeStatus();
            mc.THomePrm tHomePrm = new mc.THomePrm();
            cmb_moveDir.Invoke(new Action(() =>
            {
                switch (Convert.ToInt16(cmb_moveDir.SelectedIndex + 1))   //
                {
                    case 1: tHomePrm.moveDir = 1;
                        break;
                    case 2: tHomePrm.moveDir = -1;
                        break;
                }
            }));
            cmb_indexDir.Invoke(new Action(() =>
            {
                switch (Convert.ToInt16(cmb_indexDir.SelectedIndex + 1))   //
                {
                    case 1: tHomePrm.indexDir = 1;
                        break;
                    case 2: tHomePrm.indexDir = -1;
                        break;
                }
            }));
            tHomePrm.edge = 0;
            tHomePrm.velHigh = (double)nud_velH.Value;
            tHomePrm.velLow = (double)nud_velL.Value;
            tHomePrm.acc = 1;
            tHomePrm.dec = 1;
            tHomePrm.smoothTime = 10;
            tHomePrm.homeOffset = 0;
            tHomePrm.searchHomeDistance = 0;
            tHomePrm.searchIndexDistance = 20000;
            tHomePrm.escapeStep = 20000;
            cmb_home.Invoke(new Action(() =>
            {
                switch (Convert.ToInt16(cmb_home.SelectedIndex + 1))   //mode
                {
                    case 1: tHomePrm.mode = mc.HOME_MODE_LIMIT;
                        break;
                    case 2: tHomePrm.mode = mc.HOME_MODE_LIMIT_HOME;
                        break;
                    case 3: tHomePrm.mode = mc.HOME_MODE_LIMIT_INDEX;
                        break;
                    case 4: tHomePrm.mode = mc.HOME_MODE_LIMIT_HOME_INDEX;
                        break;
                    case 5: tHomePrm.mode = mc.HOME_MODE_HOME;
                        break;
                    case 6: tHomePrm.mode = mc.HOME_MODE_HOME_INDEX;
                        break;
                    case 7: tHomePrm.mode = mc.HOME_MODE_INDEX;
                        break;
                }
            }));

            //回零线程
            if (threadHome == null)
            {
                threadHome = new Thread(() =>
                {
                    gCard.SmartHome(0, axisHome, tHomePrm, out tHomeStatus);
                }) { IsBackground = true };
                threadHome.Start();
            }
            else
            {
                threadHome.Abort();
                threadHome = new Thread(() =>
                {
                    gCard.SmartHome(0, axisHome, tHomePrm, out tHomeStatus);
                }) { IsBackground = true };
                threadHome.Start();
            }
            //状态监测线程
            mc.THomeStatus homeStatus = new mc.THomeStatus();
            if (threadHomeStatus == null)
            {
                threadHomeStatus = new Thread(() =>
                {
                    while(true)
                    {
                        sRtn = mc.GT_GetHomeStatus(0,axisHome,out homeStatus );
                        this.Invoke(new Action(() =>
                        {
                            txt_homeRun.Text = homeStatus.run.ToString();
                            txt_homeStage.Text = homeStatus.stage.ToString();
                            txt_homeError.Text = homeStatus.error.ToString();
                            txt_capturePos.Text = homeStatus.capturePos.ToString();
                            txt_targetPos.Text = homeStatus.targetPos.ToString();
                        }));
                    }
                }){ IsBackground = true };
                threadHomeStatus.Start();
            }
            else
            {
                threadHomeStatus.Abort();
                threadHomeStatus = new Thread(() =>
                {
                    while (true)
                    {
                        sRtn = mc.GT_GetHomeStatus(0, axisHome, out homeStatus);
                        this.BeginInvoke(new Action(() =>
                        {
                            //Thread.Sleep(5);
                            txt_homeRun.Text = homeStatus.run.ToString();
                            txt_homeStage.Text = homeStatus.stage.ToString();
                            txt_homeError.Text = homeStatus.error.ToString();
                            txt_capturePos.Text = homeStatus.capturePos.ToString();
                            txt_targetPos.Text = homeStatus.targetPos.ToString();
                        }));
                    }
                }) { IsBackground = true };
                threadHomeStatus.Start();
            }

        }

        private void btn_homeStop_Click(object sender, EventArgs e)
        {
            sRtn = gts.mc.GT_Stop(0, 1 << (short)(cmb_selectAxis.SelectedIndex + 1) - 1, 0);
        }

        //电子齿轮
        private void GearUse(object sender, EventArgs e)
        {
            short filter = Convert.ToInt16(txt_filter.Text);
            short gear = 1;   //跟随方式
            short axisM = Convert.ToInt16(this.cmb_selectAxis.SelectedIndex + 1);   //主轴
            short axisF = Convert.ToInt16(this.cmb_gearAxis.SelectedIndex + 1); //从轴
            int slope = Convert.ToInt32(txt_gearSlope.Text);    //离合区
            int even =Convert.ToInt32(txt_gearEven.Text);   //齿轮比  从/主
            if (chk_gear.Checked == true)
            {
                chk_follow.Checked = false;
                if (axisM == axisF)
                {
                    MessageBox.Show("GEAR模式主轴与从轴轴号不能相同！");
                    chk_gear.Checked = false;
                }
                else
                {
                    switch (this.cmb_gearMode.SelectedIndex + 1)
                    {
                        case 1:
                            gear = mc.GEAR_MASTER_PROFILE;
                            break;
                        case 2:
                            gear = mc.GEAR_MASTER_ENCODER;
                            break;
                        case 3:
                            gear = mc.GEAR_MASTER_AXIS;
                            break;
                        default: break;
                    }
                    //sRtn = mc.GT_SetAxisPrfVelFilter(0, axisF, filter);
                    gCard.Gear(0, axisM, axisF, 0, gear, even, slope);
                }
            }
            else if (chk_gear.Checked == false)
            {
                axisF = Convert.ToInt16(this.cmb_gearAxis.SelectedIndex + 1); //从轴
                sRtn = gts.mc.GT_Stop(0, 1 << axisF - 1, 0);
                sRtn = mc.GT_PrfTrap(0, axisF);
            }
        }

        //电子凸轮
        private void FollowUse(object sender, EventArgs e)
        {
            short follow = 1;   //跟随方式
            short filter = Convert.ToInt16(txt_filter.Text);
            short axisM = Convert.ToInt16(this.cmb_selectAxis.SelectedIndex + 1);   //主轴
            short axisF = Convert.ToInt16(this.cmb_followAxis.SelectedIndex + 1); //从轴
            int masterPostion = Convert.ToInt32(txt_masterPostion.Text);    //主轴位移
            double followPostion = Convert.ToDouble(txt_followPostion.Text);   //从轴位移  从/主
            if (chk_follow.Checked == true)
            {
                chk_gear.Checked = false;
                if (axisM == axisF)
                {
                    MessageBox.Show("FOLLOW模式主轴与从轴轴号不能相同！");
                    chk_follow.Checked = false;
                }
                else
                {
                    switch (this.cmb_followAxis.SelectedIndex + 1)
                    {
                        case 1:
                            follow = mc.FOLLOW_MASTER_PROFILE;
                            break;
                        case 2:
                            follow = mc.FOLLOW_MASTER_ENCODER;
                            break;
                        case 3:
                            follow = mc.FOLLOW_MASTER_AXIS;
                            break;
                        default: break;
                    }
                    sRtn = mc.GT_PrfFollow(0, axisF, 0);//双向跟随Follow
                    sRtn = mc.GT_FollowClear(0, axisF, 0);
                    //sRtn = mc.GT_SetAxisPrfVelFilter(0, axisF, filter);
                    sRtn = mc.GT_SetFollowMaster(0, axisF, axisM, follow, 0);//Follow运动下主轴设置
                    sRtn = mc.GT_FollowData(0, axisF, masterPostion / 3, followPostion / 3, mc.FOLLOW_SEGMENT_NORMAL, 0);
                    sRtn = mc.GT_FollowData(0, axisF, masterPostion * 2 / 3, followPostion * 2 / 3, mc.FOLLOW_SEGMENT_NORMAL, 0);
                    sRtn = mc.GT_FollowData(0, axisF, masterPostion, followPostion, mc.FOLLOW_SEGMENT_NORMAL, 0);
                    sRtn = mc.GT_SetFollowEvent(0, axisF, mc.FOLLOW_EVENT_START, 1, 0);
                    sRtn = mc.GT_FollowStart(0, 1 << (axisF - 1), 0);//启动Follow运动
                }
            }
            else if (chk_follow.Checked == false)
            {
                axisF = Convert.ToInt16(this.cmb_followAxis.SelectedIndex + 1); //从轴
                sRtn = gts.mc.GT_Stop(0, 1 << axisF - 1, 0);
                sRtn = mc.GT_PrfTrap(0, axisF);
            }
        }

        private void btn_monitorAxis_Click(object sender, EventArgs e)
        {
            Monitor monitorAxis = new Monitor();
            monitorAxis.Show();
        }

        int posX, posY, posType;
        List<string> tempData = new List<string> { };//加载文件点位集合
        List<string> list = new List<string> { };//插补数据存储
        List<string> tempList = new List<string> { };//插补数据存储
        Double synVel = 100, synAcc = 0, evenTime = 20;
        mc.TCrdData pLookAhead = new mc.TCrdData();
        private void btn_setCoordinate_Click(object sender, EventArgs e)
        {
            //前瞻初始化
            gts.mc.TCrdData temp = new gts.mc.TCrdData();
            gts.mc.TCrdData[] crdData = new gts.mc.TCrdData[200];
            int size = Marshal.SizeOf(temp) * 200;
            IntPtr pCrdData = Marshal.AllocHGlobal(size);
            //******第一步建二维立坐标系
            //建立二维坐标系1，XY对应12轴，使用fifo0作为主运动数据存储。
            mc.TCrdPrm crdPrm = new mc.TCrdPrm();
            crdPrm.dimension = 2;                        // 建立二维的坐标系
            crdPrm.synVelMax = 500;                      // 坐标系的最大合成速度是: 500 pulse/ms
            crdPrm.synAccMax = 2;                        // 坐标系的最大合成加速度是: 2 pulse/ms^2
            crdPrm.evenTime = 0;                         // 坐标系的最小匀速时间为0
            crdPrm.profile1 = 1;                         // 规划器1对应到X轴                       
            crdPrm.profile2 = 2;                         // 规划器2对应到Y轴
            crdPrm.profile3 = 0;
            crdPrm.profile4 = 0;
            crdPrm.profile5 = 0;
            crdPrm.profile6 = 0;
            crdPrm.profile7 = 0;                         // 若profile7为1，规划器7对应到X轴           
            crdPrm.profile8 = 0;
            crdPrm.setOriginFlag = 1;                    // 需要设置加工坐标系原点位置
            crdPrm.originPos1 = 0;                       // 加工坐标系原点位置在(0,0)，即与机床坐标系原点重合
            crdPrm.originPos2 = 0;
            crdPrm.originPos3 = 0;
            crdPrm.originPos4 = 0;
            crdPrm.originPos5 = 0;
            crdPrm.originPos6 = 0;
            crdPrm.originPos7 = 0;
            crdPrm.originPos8 = 0;
            sRtn = gts.mc.GT_SetCrdPrm(0, 1, ref crdPrm);   //必须在轴调用停止状态下,重建坐标系会清除原有数据
            sRtn = mc.GT_CrdClear(0, 1, 0); //清除坐标系1 FIFO0中的数据缓存。
            sRtn = mc.GT_InitLookAhead(0,           //卡号
                                       1,           //坐标系
                                       0,           //FIFO
                                       5,           //拐角时间T
                                       50,           //accMax
                                      200,         //数据段N
                                      pCrdData);//结构体crdData
        }

        private void btn_addData_Click(object sender, EventArgs e)
        {

            short circleDir;
            int mode = cmb_cb.SelectedIndex;                 //插补类型
            double radius = Convert.ToDouble(txt_ChaBuR.Text);
            double xCenter = Convert.ToDouble(txt_ChaBuCX.Text);  //圆心坐标X
            double yCenter = Convert.ToDouble(txt_ChaBuCY.Text);   //圆心坐标Y
            posX = Convert.ToInt32(txt_ChaBuX.Text);             //XY坐标
            posY = Convert.ToInt32(txt_ChaBuY.Text);
            synVel = 30;    //插补速度
            synAcc = 1;     //插补加速度
            evenTime = 0;   //插补终点速度

            switch (mode)            //判断插补模式        
            {
                case 0:
                    sRtn = mc.GT_LnXY(0, 1, posX, posY, synVel, synAcc, evenTime, 0);
                    tempData.Add(Convert.ToString(posX));
                    tempData.Add(Convert.ToString(posY));
                    tempData.Add(Convert.ToString(" "));
                    tempData.Add(Convert.ToString(" "));
                    tempData.Add(Convert.ToString(" "));
                    tempData.Add("Line");
                    break;
                case 1:
                    circleDir = 0;//圆弧插补方向   0：顺1：逆
                    sRtn = mc.GT_ArcXYC(0, 1, posX, posY, xCenter, yCenter, circleDir, synVel, synAcc, evenTime, 0);
                    tempData.Add(Convert.ToString(posX));
                    tempData.Add(Convert.ToString(posY));
                    tempData.Add(Convert.ToString(xCenter));
                    tempData.Add(Convert.ToString(yCenter));
                    tempData.Add(Convert.ToString(" "));
                    tempData.Add("Arc");
                    break;
                case 2:
                    circleDir = 1;
                    sRtn = mc.GT_ArcXYC(0, 1, posX, posY, xCenter, yCenter, circleDir, synVel, synAcc, evenTime, 0);
                    tempData.Add(Convert.ToString(posX));
                    tempData.Add(Convert.ToString(posY));
                    tempData.Add(Convert.ToString(xCenter));
                    tempData.Add(Convert.ToString(yCenter));
                    tempData.Add(Convert.ToString(" "));
                    tempData.Add("Arc");
                    break;
                case 3:                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                    circleDir = 0;
                    sRtn = mc.GT_ArcXYR(0, 1, posX, posY, radius, circleDir, synVel, synAcc, evenTime, 0);
                    tempData.Add(Convert.ToString(posX));
                    tempData.Add(Convert.ToString(posY));
                    tempData.Add(Convert.ToString(" "));
                    tempData.Add(Convert.ToString(" "));
                    tempData.Add(Convert.ToString(radius));
                    tempData.Add("ArcR");
                    break;
                case 4:
                    circleDir = 1;
                    sRtn = mc.GT_ArcXYR(0, 1, posX, posY, radius, circleDir, synVel, synAcc, evenTime, 0);
                    tempData.Add(Convert.ToString(posX));
                    tempData.Add(Convert.ToString(posY));
                    tempData.Add(Convert.ToString(" "));
                    tempData.Add(Convert.ToString(" "));
                    tempData.Add(Convert.ToString(radius));
                    tempData.Add("ArcR");
                    break;
            }
        }
        Thread threadInterpositionStart;
        Thread threadInterpositionStatus;
        int pSpace,
            pSegment;
        short pRun;
        private void btn_cbStart_Click(object sender, EventArgs e)
        {
            sRtn = mc.GT_CrdData(0, 1, System.IntPtr.Zero, 0);
            sRtn = mc.GT_CrdStart(0, 1, 0);

            if (threadInterpositionStatus == null)
            {
                threadInterpositionStatus = new Thread(() =>
                {
                    while (true)
                    {
                        sRtn = mc.GT_CrdSpace(0, 1, out pSpace, 0);
                        txt_crdSpace.BeginInvoke(new Action(() =>
                        {
                            txt_crdSpace.Text = pSpace.ToString();
                        }));
                        sRtn = mc.GT_CrdStatus(0, 1, out pRun, out pSegment, 0);
                        txt_crdRun.BeginInvoke(new Action(() =>
                        {
                            txt_crdRun.Text = pRun.ToString();
                        }));
                        txt_crdSegment.BeginInvoke(new Action(() =>
                        {
                            txt_crdSegment.Text = pSegment.ToString();
                        }));
                    }
                    
                });
                threadInterpositionStatus.IsBackground = true;
                threadInterpositionStatus.Start();
            }
        }

        private void btn_cbStop_Click(object sender, EventArgs e)
        {
            sRtn = mc.GT_Stop(0, 1 << (1 - 1), 0);
            sRtn = mc.GT_Stop(0, 1 << (2 - 1), 0);
        }

        private void btn_displayData_Click(object sender, EventArgs e)
        {
            int mode = cmb_cb.SelectedIndex; 
            DataTable dt = new DataTable("参数显示");
            dgv_displayData.AllowUserToResizeColumns = true;
            dgv_displayData.ReadOnly = true;  //单元格不可编辑
            //dataGridView1.AllowUserToAddRows = true;
            dgv_displayData.AllowUserToDeleteRows = false;
            dgv_displayData.Font = new System.Drawing.Font("宋体", 10);
            dgv_displayData.Columns.Clear();

            dt.Columns.Add(new DataColumn("X轴参数", typeof(string)));
            dt.Columns.Add(new DataColumn("Y轴参数", typeof(string)));
            dt.Columns.Add(new DataColumn("圆心X坐标", typeof(string)));
            dt.Columns.Add(new DataColumn("圆心Y坐标", typeof(string)));
            dt.Columns.Add(new DataColumn("圆R长度", typeof(string)));
            dt.Columns.Add(new DataColumn("插补类型", typeof(string)));
            for (var i = 0; i < tempData.Count; i += 6)
            {
                DataRow dr = dt.NewRow();
                dr["X轴参数"] = tempData[i];
                dr["Y轴参数"] = tempData[i + 1];
                dr["圆心X坐标"] = tempData[i + 2];
                dr["圆心Y坐标"] = tempData[i + 3];
                dr["圆R长度"] = tempData[i + 4];
                dr["插补类型"] = tempData[i + 5];
                dt.Rows.Add(dr);
            }
            dgv_displayData.DataSource = dt;
        }


        private void btn_clearData_Click(object sender, EventArgs e)
        {
            tempData.Clear();
            dgv_displayData.DataSource = null;
            sRtn = mc.GT_CrdClear(0, 1, 0);
        }
        //位置比较的运动程序
        private void Move()
        {
            short runSts;
            int segment;
            int pos;
            int space;
            double vel;
            gts.mc.TCrdPrm crdPrm;

            crdPrm.dimension = 2;                        // 建立二维的坐标系
            crdPrm.synVelMax = 500;                      // 坐标系的最大合成速度是: 500 pulse/ms
            crdPrm.synAccMax = 2;                        // 坐标系的最大合成加速度是: 2 pulse/ms^2
            crdPrm.evenTime = 0;                         // 坐标系的最小匀速时间为0
            crdPrm.profile1 = 1;                         // 规划器1对应到X轴                       
            crdPrm.profile2 = 2;                         // 规划器2对应到Y轴
            crdPrm.profile3 = 0;
            crdPrm.profile4 = 0;
            crdPrm.profile5 = 0;
            crdPrm.profile6 = 0;
            crdPrm.profile7 = 0;
            crdPrm.profile8 = 0;
            crdPrm.setOriginFlag = 0;                    // 需要设置加工坐标系原点位置
            crdPrm.originPos1 = 0;                       // 加工坐标系原点位置在(0,0)，即与机床坐标系原点重合
            crdPrm.originPos2 = 0;
            crdPrm.originPos3 = 0;
            crdPrm.originPos4 = 0;
            crdPrm.originPos5 = 0;
            crdPrm.originPos6 = 0;
            crdPrm.originPos7 = 0;
            crdPrm.originPos8 = 0;
            sRtn = gts.mc.GT_SetCrdPrm(0, 1, ref crdPrm);
            sRtn = gts.mc.GT_CrdClear(0, 1, 0);
            sRtn = gts.mc.GT_LnXY(0,
                1,                  //坐标系1
                Convert.ToInt32(txt_compareX1.Text), Convert.ToInt32(txt_compareY1.Text),       //终点坐标
                10,                 //目标速度 pulse/ms
                0.1,                //加速度   pulse/ms^2
                0,                  //终点速度 0
                0);                 //插补缓存区号0/1
            sRtn = gts.mc.GT_LnXY(0,
                1,                  //坐标系1
                Convert.ToInt32(txt_compareX2.Text), Convert.ToInt32(txt_compareY2.Text),       //终点坐标
                10,                 //目标速度 pulse/ms
                0.1,                //加速度   pulse/ms^2
                0,                  //终点速度 0
                0);   
            sRtn = gts.mc.GT_CrdSpace(0, 1, out space, 0);
            sRtn = gts.mc.GT_CrdStart(0, 1, 0);
            //sRtn = gts.mc.GT_CrdStatus(0, 1, out runSts, out segment, 0);
            //int psts;
            //uint pc;
            //do
            //{
            //    mc.GT_GetSts(0, 1, out psts, 1, out pc);
            //} while ((psts & 0x400) != 0); 
        }

        private void DoCompare1()
        {
            int[] buf1 = new int[100];//HSIO0输出点位
            for (int i = 0; i < 100;i++ )
            {
                buf1[i] =1+ Convert.ToInt32(txt_compareX1.Text) + (i) * (Convert.ToInt32(txt_compareX2.Text) - Convert.ToInt32(txt_compareX1.Text)) / 100;
            }
            int[] buf2 = new int[1];//new int[1];//HSIO1i输出点位
            Move();
            sRtn = gts.mc.GT_CompareData(0,
                                         1, //编码器轴号
                                         1, //比较源 0：脉冲计数器 1：编码器
                                         0, //hsio输出方式 0：脉冲 1：电平反转
                                         0, //HSIO 输出的初始电平
                //0：表示位置比较输出引脚初始电平为复位状态（恢复到初始化后的电平状态）；
                //1：表示位置比较输出引脚初始电平为取反状态（与初始化后的电平状态相反）。
                                         100, //输出为脉冲时设置脉冲宽度：范围1-32767us
                                         ref buf1[0],//HSIO0 的比较位置缓冲区， 位置值为相对于调用该指令时的当前位置的偏移，必须是单调上升的正数序列或单调下降的负数序列
                                         Convert.ToInt16(buf1.Length), //pBuf1 的长度，最大值为 4096
                                         ref buf2[0], //HSIO1 的比较位置缓冲区， 位置值为相对于调用该指令时的当前位置的偏移，必须是单调上升的正数序列或单调下降的负数序列。且 pBuf1 和 pBuf2 的单调性必须相同
                                         0);//pBuf2 的长度，最大值为 4096
            sRtn = mc.GT_SetComparePort(0, mc.COMPARE_PORT_GPO, 0, 1);//输出到GPO0；
        }


        mc.T2DCompareData[] dataBuf = new mc.T2DCompareData[1];
        mc.T2DCompareData[] dataIn = new mc.T2DCompareData[3000];
        mc.T2DComparePrm prm; //二维位置比较输出参数
        short pStatus,
            pStatusE,//比较输出状态：1为完成，0为正在进行
            pFifo,//当前空闲fifo
            pFifoCount,//当前空闲fifo剩余空间
            pBufCount;//FPGA 中 FIFO 剩余空间， FPGA 的 FIFO 总大小为 512，启动位置比较之前，压入的数据先进入 FPGA 的 FIFO
        int pCount, pCountE;//位置比较已输出次数
        private void DoCompare2()
        {
            for (int i = 0; i < 3000; i++)
            {
                dataIn[i].px = 0;
                dataIn[i].py = 1 + Convert.ToInt32(txt_compareX1.Text)+(Convert.ToInt32(txt_compareX2.Text) - Convert.ToInt32(txt_compareX1.Text)) / 3000 * i;
            }
            short t;
            sRtn = mc.GT_2DCompareClear(0, 0);//清空HSIO0
            sRtn = mc.GT_2DCompareMode(0, 0, mc.COMPARE2D_MODE_1D);//设置二维位置比较输出一维模式
            prm.encx = 1;       // 1D模式下无效，不能为0
            prm.ency = 1;       // 设为1
            prm.maxerr = 10;   // 最大误差Pulse
            prm.outputType = 0; // 输出类型 = 脉冲
            prm.source = 0;     // 比较源0 ：规划1：编码器
            prm.startLevel = 0; //起始电平方式0：位置比较输出引脚电平复位    1：位置比较输出引脚电平取反
            prm.threshold = 0; // 最优点计算阈值
            prm.time = 500;   // 脉冲宽度 us
            sRtn = mc.GT_2DCompareSetPrm(0, 0, ref prm);
            sRtn = mc.GT_SetComparePort(0, mc.COMPARE_PORT_GPO, 0, 1);//输出到GPO0；
            sRtn = mc.GT_2DCompareStart(0, 0);
            Move();
            for (int i = 0; i < 3000; i++)
            {
                dataBuf[0].px = 0;
                dataBuf[0].py = (int)dataIn[i].py;
                do
                {
                    t = mc.GT_2DCompareStatus(0, 0, out pStatus, out pCount, out pFifo, out pFifoCount, out pBufCount);
                    t = mc.GT_2DCompareData(0, 0, 1, ref dataBuf[0], pFifo);//压入数据 
                } while (t != 0);//通过判断返回值来确定数据是否压入成功；
            }
        }

        private void DoCompare3()
        {
            for (int i = 0; i < 3000; i++)
            {
                dataIn[i].px = Convert.ToInt32(txt_compareX1.Text) + (Convert.ToInt32(txt_compareX2.Text) - Convert.ToInt32(txt_compareX1.Text)) / 3000 * i;
                dataIn[i].py = Convert.ToInt32(txt_compareY1.Text) + (Convert.ToInt32(txt_compareY2.Text) - Convert.ToInt32(txt_compareY1.Text)) / 3000 * i;
            }
            short t;
            sRtn = mc.GT_2DCompareClear(0, 0);
            sRtn = mc.GT_2DCompareMode(0, 0, mc.COMPARE2D_MODE_2D);
            prm.encx = 1;       // X 轴为1轴
            prm.ency = 2;       // Y 轴为2轴
            prm.maxerr = 10;   // 最大误差Pulse
            prm.outputType = 0; // 输出类型 = 脉冲
            prm.source = 0;     // 比较源0 ：规划1：编码器
            prm.startLevel = 0; //起始电平方式0：位置比较输出引脚电平复位    1：位置比较输出引脚电平取反
            prm.threshold = 0; // 最优点计算阈值
            prm.time = 50;   // 脉冲宽度 us
            sRtn = mc.GT_2DCompareSetPrm(0, 0, ref prm);
            sRtn = mc.GT_SetComparePort(0, mc.COMPARE_PORT_GPO, 0, 1);
            sRtn = mc.GT_2DCompareStart(0, 0);
            Move();
            for (int i = 0; i < 3000; i++)
            {
                dataBuf[0].px = (int)dataIn[i].px;
                dataBuf[0].py = (int)dataIn[i].py;
                do
                {
                    t = mc.GT_2DCompareStatus(0, 0, out pStatus, out pCount, out pFifo, out pFifoCount, out pBufCount);
                    t = mc.GT_2DCompareData(0, 0, 1, ref dataBuf[0], pFifo);//压入数据 
                } while (t != 0);
            }
        }

        Thread compare1Start;
        Thread compareStatus;
        private void btn_compareSatrt_Click(object sender, EventArgs e)
        {
            if (compare1Start == null)
            {
                if (compareType == 0)
                {
                    compare1Start = new Thread(new ThreadStart(DoCompare1));//启动位置比较输出
                }
                else if (compareType == 1)
                {
                    compare1Start = new Thread(new ThreadStart(DoCompare2));//启动位置比较输出
                }
                else if (compareType == 2)
                {
                    compare1Start = new Thread(new ThreadStart(DoCompare3));//启动位置比较输出
                }
                compare1Start.IsBackground = true;
                compare1Start.Start();
            }
            else 
            {
                compare1Start.Abort();
                if (compareType == 0)
                {
                    compare1Start = new Thread(new ThreadStart(DoCompare1));//启动位置比较输出
                }
                else if (compareType == 1)
                {
                    compare1Start = new Thread(new ThreadStart(DoCompare2));//启动位置比较输出
                }
                else if (compareType == 2)
                {
                    compare1Start = new Thread(new ThreadStart(DoCompare3));//启动位置比较输出
                }
                compare1Start.IsBackground = true;
                compare1Start.Start();
            }

            if (compareStatus == null)
            {
                compareStatus = new Thread(() =>
                {
                    if (compareType == 1 || compareType == 2)
                    {
                        while (true)
                        {
                            sRtn = mc.GT_2DCompareStatus(0, 0, out pStatus, out pCount, out pFifo, out pFifoCount, out pBufCount);//位置比较输出状态
                            txt_compareStatus.Invoke(new Action(() => { txt_compareStatus.Text = Convert.ToString(pStatus); }));
                            txt_compareCount.Invoke(new Action(() => { txt_compareCount.Text = Convert.ToString(pCount); }));
                        }
                    }
                    else 
                    {   
                        short status;
                        int count;
                        if (compareType == 0)
                        {
                            while (true)
                            {
                                sRtn = mc.GT_CompareStatus(0, out status, out count);//位置比较输出状态
                                txt_compareStatus.Invoke(new Action(() => { txt_compareStatus.Text = Convert.ToString(status); }));
                                txt_compareCount.Invoke(new Action(() => { txt_compareCount.Text = Convert.ToString(count); }));
                            }
                        }
                    }
                });
                compareStatus.IsBackground = true;
                compareStatus.Start();
            }
            else
            {
                compareStatus.Abort();
                compareStatus = new Thread(() =>
                {
                    if (compareType == 1 || compareType == 2)
                    {
                        while (true)
                        {
                            sRtn = mc.GT_2DCompareStatus(0, 0, out pStatus, out pCount, out pFifo, out pFifoCount, out pBufCount);//位置比较输出状态
                            txt_compareStatus.Invoke(new Action(() => { txt_compareStatus.Text = Convert.ToString(pStatus); }));
                            txt_compareCount.Invoke(new Action(() => { txt_compareCount.Text = Convert.ToString(pCount); }));
                        }
                    }
                    else
                    {
                        short status;
                        int count;
                        if (compareType == 0)
                        {
                            while (true)
                            {
                                sRtn = mc.GT_CompareStatus(0, out status, out count);//位置比较输出状态
                                txt_compareStatus.Invoke(new Action(() => { txt_compareStatus.Text = Convert.ToString(status); }));
                                txt_compareCount.Invoke(new Action(() => { txt_compareCount.Text = Convert.ToString(count); }));
                            }
                        }
                    }
                });
                compareStatus.IsBackground = true;
                compareStatus.Start();
            }
        }

        short compareType;
        private void cmb_compareChanged(object sender, EventArgs e)
        {
            switch (cmb_compareMode.SelectedIndex)
            {
                case 0:
                    compareType = 0;
                    txt_compareY1.Invoke(new Action(() => { txt_compareY1.Enabled = false; txt_compareY1.Text = "0"; }));
                    txt_compareY2.Invoke(new Action(() => { txt_compareY2.Enabled = false; txt_compareY2.Text = "0"; }));
                    break;
                case 1:
                    compareType = 1;
                    txt_compareY1.Invoke(new Action(() => { txt_compareY1.Enabled = false; txt_compareY1.Text = "0"; }));
                    txt_compareY2.Invoke(new Action(() => { txt_compareY2.Enabled = false; txt_compareY2.Text = "0"; }));
                    break;
                case 2:
                    compareType = 2;
                    txt_compareY1.BeginInvoke(new Action(() => { txt_compareY1.Enabled = true; txt_compareY1.Text = "0"; }));
                    txt_compareY2.BeginInvoke(new Action(() => { txt_compareY2.Enabled = true; txt_compareY2.Text = "20000"; }));
                    break;
            }
        }

        private void btn_compareStop_Click(object sender, EventArgs e)
        {
            sRtn = mc.GT_Stop(0, 1 << (1 - 1), 0);
            sRtn = mc.GT_Stop(0, 1 << (2 - 1), 0);
            sRtn = mc.GT_CompareStop(0);
        }

        private void CheckReselect(object sender, EventArgs e)
        {
            chk_follow.Checked = false;
        }
        private void CheckReselectG(object sender, EventArgs e)
        {
            chk_gear.Checked = false;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            short pointNum = 11;
            int startPos = 1000;
            int posLen = 10000;
            int[] positiveCom = new int[pointNum];
            int[] negativeCom = new int[pointNum];
            positiveCom[0] = 4;
            negativeCom[0] = 4;
            for (int i = 1; i < pointNum; i++)
            {
                positiveCom[i] = positiveCom[i - 1] + 4;
                negativeCom[i] = negativeCom[i - 1] + 4;
            }
            gts.mc.GT_SetLeadScrewComp(0,1, pointNum, startPos, posLen,out positiveCom[0],out negativeCom[0]);
            //int[] pPos = new int[200];
            //int[] nPos = new int[200];
            //sRtn = mc.GT_SetLeadScrewComp(0, 1, 200, 0, 10000, out pPos[0], out nPos[0]);
        }

    }
}
